package com.atguigu.order.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.atguigu.common.constants.OrderConstant;
import com.atguigu.common.exception.NotStockException;
import com.atguigu.common.to.SeckillOrderTo;
import com.atguigu.common.utils.R;

import com.atguigu.common.vo.FareVo;
import com.atguigu.common.vo.MemberAddressVo;
import com.atguigu.common.vo.MemberResponseVo;
import com.atguigu.common.vo.OrderVo;
import com.atguigu.order.entity.OrderItemEntity;
import com.atguigu.order.entity.PaymentInfoEntity;
import com.atguigu.order.enume.OrderStatusEnum;
import com.atguigu.order.feign.CartFeignService;
import com.atguigu.order.feign.MemberFeignService;
import com.atguigu.order.feign.ProductFeignService;
import com.atguigu.order.feign.WmsFeignService;
import com.atguigu.order.interceptor.LoginUserInterceptor;
import com.atguigu.order.service.OrderItemService;
import com.atguigu.order.to.OrderCreateTo;
import com.atguigu.order.to.SpuInfoTo;
import com.atguigu.order.vo.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;



import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.order.dao.OrderDao;
import com.atguigu.order.entity.OrderEntity;
import com.atguigu.order.service.OrderService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;


@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {

    public static final ThreadLocal<OrderSubmitVo> submitVoThreadLocal = new ThreadLocal<>();

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private MemberFeignService memberFeignService;

    @Autowired
    private CartFeignService cartFeignService;

    @Autowired
    private WmsFeignService wmsFeignService;

    @Autowired
    private ProductFeignService productFeignService;

    @Autowired
    private ThreadPoolExecutor excutors;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<OrderEntity> page = this.page(
                new Query<OrderEntity>().getPage(params),
                new QueryWrapper<OrderEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public OrderConfirmVo confirmOrder() throws ExecutionException, InterruptedException {

        OrderConfirmVo orderItemVo = new OrderConfirmVo();
        MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();
        System.out.println("主线程id->" + Thread.currentThread().getId());
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

        /**
         * feign丢失请求头：
         * 出现问题的原因： 当我们不使用异步编排的时候也就是单线程执行的时候，
         * 请求上下文持有器即：RequestContextHolder采用的是ThreadLocal存储请求对象。
         * 当我们采用异步编排时，而是多个线程去执行，新建的线程会丢失请求对象。
         */

        CompletableFuture<Void> getAddressFuture = CompletableFuture.runAsync(() -> {
            System.out.println("member线程id->" + Thread.currentThread().getId());
            //每一个线程都共享之前的请求数据
            RequestContextHolder.setRequestAttributes(requestAttributes);
            //1.远程查询所有收获地址列表
            List<MemberAddressVo> address = memberFeignService.getAddress(memberResponseVo.getId());
            orderItemVo.setMemberAddressVos(address);
        }, excutors);


        CompletableFuture<Void> getCartItemFuture = CompletableFuture.runAsync(() -> {
            System.out.println("cart线程id->" + Thread.currentThread().getId());
            //每一个线程都共享之前的请求数据
            RequestContextHolder.setRequestAttributes(requestAttributes);
            //2.远程查询商品列表
            List<OrderItemVo> cartItems = cartFeignService.getCurrentUserCartItems();
            orderItemVo.setItems(cartItems);
        }, excutors).thenRunAsync(()->{

            List<OrderItemVo> items = orderItemVo.getItems();
            List<Long> skuIds = items.stream()
                    .map(OrderItemVo::getSkuId)
                    .collect(Collectors.toList());
            R r = wmsFeignService.getSkuHasStock(skuIds);
            List<SkuStockVo> skuStockVos = r.getData(new TypeReference<List<SkuStockVo>>(){});
            Map<Long, Boolean> map = skuStockVos.stream().collect(Collectors.toMap(SkuStockVo::getSkuId, SkuStockVo::getHasStock));
            orderItemVo.setHasStock(map);

        }, excutors);


        /**
         *  远程调用购物车服务丢失请求头，取不到session里面的用户信息
         *  1.浏览器发送请求头自动带了cookie访问订单服务
         *  2. order服务远程调用cart服务这个请求没有任何请求头
         *  3. 没有请求头cart认为没登录
         *  原因：feign远程调用默认请求头无信息是空的，原理就是feign在远程调用之前要构造请求，调用很多的拦截器for (RequestInterceptor interceptor : requestInterceptors)
         *  解决办法：加上feign远程调用拦截器，创建新的request，老请求远程调用 Cookie等请求头必须和老请求同步过来
         */

        //3.设置用户积分信息
        orderItemVo.setIntegration(memberResponseVo.getIntegration());
        //4.其他数据自动计算
        //TODO 5.防重令牌
        //防重令牌 redis中存一份 页面存储一份
        String token = UUID.randomUUID().toString().replace("-", "");
        //将防重令牌存入redis
        redisTemplate.opsForValue().set(OrderConstant.USER_ORDER_TOKEN_PREFIX + memberResponseVo.getId(),
                token, 30, TimeUnit.MINUTES);
        //将防重令牌交给页面
        orderItemVo.setOrderToken(token);

        //等待所有任务完成
        CompletableFuture.allOf(getAddressFuture, getCartItemFuture).get();
        return orderItemVo;
    }

    /**
     * 本地事务: 在分布式系统，只能控制住自己的回滚，控制不了其他服务的回滚
     * 分布式事务: 最大原因。网络问题+分布式机器
     *
     * 本地事务会失效不回滚的两种情况：
     * ①锁库存假失败，由于网络原因导致连接超时，但是锁库存已经操作成功。此时，订单数据回滚而锁库存数据没有回滚。
     * ②其它远程服务调用失败，订单数据回滚，但是已经执行成功的远程服务调用的数据库数据无法回滚
     * @param vo
     * @return
     */
    // @GlobalTransactional
    @Transactional
    @Override
    public SubmitOrderResponseVo submitOrder(OrderSubmitVo vo) {
        // submitVoThreadLocal.set(vo);
        //1. 验证令牌【令牌的对比和删除必须保证原子性】
        SubmitOrderResponseVo submitOrderResponseVo = new SubmitOrderResponseVo();
        submitOrderResponseVo.setCode(0);
        String token = vo.getOrderToken();
        MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();

        String script= "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Long result = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class),
                Arrays.asList(OrderConstant.USER_ORDER_TOKEN_PREFIX + memberResponseVo.getId()),
                token);
        if (result==0L) {
            //令牌验证不通过
            submitOrderResponseVo.setCode(1);
            return submitOrderResponseVo;
        } else {

            //令牌验证通过
            //1.下单: 去创建订单，验证令牌，验证价格，锁库存
            OrderCreateTo orderCreateTo = createOrder(memberResponseVo, vo);
            //2.验价: 页面提交价格与计算的价格相差小于0.01则验价成功
            BigDecimal payAmount = orderCreateTo.getOrder().getPayAmount();
            BigDecimal payPrice = vo.getPayPrice();
            if (Math.abs(payAmount.subtract(payPrice).doubleValue()) < 0.01) {
                //金额对比
                //TODO 3.保存订单(将订单保存到数据库)
                saveOrder(orderCreateTo);
                //锁定库存(当库存不足或各种问题时撤销订单保存方法， 有问题就抛异常，有异常事务就回滚)   订单号、所有订单项(skuId, skuName, num)
                WareSkuLockVo wareSkuLockVo = new WareSkuLockVo();
                wareSkuLockVo.setOrderSn(orderCreateTo.getOrder().getOrderSn());
                List<OrderItemVo> locks = orderCreateTo.getOrderItems().stream().map((orderItemEntity) -> {
                    OrderItemVo orderItemVo = new OrderItemVo();
                    orderItemVo.setSkuId(orderItemEntity.getSkuId());
                    orderItemVo.setCount(orderItemEntity.getSkuQuantity());
                    orderItemVo.setTitle(orderItemEntity.getSkuName());
                    return orderItemVo;
                }).collect(Collectors.toList());
                wareSkuLockVo.setLocks(locks);
                //库存成功了，但是网络原因超时了，订单回滚，库存不滚
                //TODO 4.远程锁库存
                R r = wmsFeignService.orderLockStock(wareSkuLockVo);
                if (r.getCode()==0) {
                    //锁定成功
                    submitOrderResponseVo.setOrder(orderCreateTo.getOrder());
                    //TODO 5. 远程扣减积分、出异常
                    //为了保证高并发。库存服务自己回滚。可以发消息给库存服务
                    ///库存服务本身也可以使用自动解锁模式   消息队列
                    // int i = 10/0;

                    //TODO 发送消息到订单延迟队列，判断过期订单
                    rabbitTemplate.convertAndSend("order-event-exchange", "order.create.order", orderCreateTo.getOrder());
                    return submitOrderResponseVo;
                } else {
                    //锁定失败
                    throw new NotStockException("库存锁定失败, 商品库存不足");
                /*    submitOrderResponseVo.setCode(3);
                    return submitOrderResponseVo;*/
                }

            }else{
                submitOrderResponseVo.setCode(2);
                return submitOrderResponseVo;
            }

        }

   /*     String redisToken = redisTemplate.opsForValue().get(OrderConstant.USER_ORDER_TOKEN_PREFIX + memberResponseVo.getId());
        if (orderToken!=null && orderToken.equals(redisToken)){
            //令牌验证通过
            redisTemplate.delete(OrderConstant.USER_ORDER_TOKEN_PREFIX + memberResponseVo.getId());
        } else {
            //不通过
        }*/
    }

    @Override
    public void closeOrder(OrderEntity order) {

        //由于下订单方法会调用解锁库存方法，并且解锁库存方法的延时队列比关单延时队列慢，所以关闭订单后，库存一定会解锁
        //发来的消息有可能不是最新的订单信息，因为之后有解锁库存的操作，所以一定要拿到最新的订单数据
        //此时发来消息说明，60分钟到了，才会到达此方法，所以需要关单

        /**
         * 订单释放和库存解锁逻辑： 当订单创建成功之后，向MQ发送关单消息，过期时间为1分钟，向MQ发送解锁库存消息，过期时间为2分钟，关单操作完成之后，过了1分钟解锁库存操作。
         * 存在问题：由于机器卡顿、消息延迟等导致关单消息未延迟发送，解锁库存消息正常发送和监听，导致解锁库存消息被消费，当执行完关单操作后便无法再执行解锁库存操作，导致卡顿的订单永远无法解锁库存。
         * 解决方案：采取主动补偿的策略。当关单操作正常完成之后，主动去发送解锁库存消息给MQ，监听解锁库存消息进行解锁。
         */

        OrderEntity orderEntity = this.getById(order.getId());
        //关单要判断订单的状态, 如果60分钟到了还是待付款状态直接关单
        if (orderEntity.getStatus()==OrderStatusEnum.CREATE_NEW.getCode()) {
            //关单: 关单就是修改订单的状态
            //为了应对高并发场景，此处不应把所有的订单信息拿去更新，而是部分字段
            this.updateById(new OrderEntity().setId(orderEntity.getId()).setStatus(4));//订单改为已关闭状态

            //关单后发送消息通知库存服务进行关单相关的操作: 解锁库存
            OrderVo orderVo = new OrderVo();
            BeanUtils.copyProperties(orderEntity, orderVo);
            rabbitTemplate.convertAndSend("order-event-exchange", "order.release.other", orderVo);
        }


    }

    @Override
    public PayVo getOrderPay(String orderSn) {

        PayVo payVo = new PayVo();
        //根据订单号查询当前订单
        OrderEntity orderEntity = this.getOne(new LambdaQueryWrapper<OrderEntity>().eq(OrderEntity::getOrderSn, orderSn));
        BigDecimal payAmount = orderEntity.getPayAmount().setScale(2, RoundingMode.UP);

        //根据订单号查询订单项
        List<OrderItemEntity> orderItems = orderItemService.list(new LambdaQueryWrapper<OrderItemEntity>().eq(OrderItemEntity::getOrderSn, orderSn));
        OrderItemEntity orderItemEntity = orderItems.get(0);

        payVo.setOut_trade_no(orderSn); // 商户订单号 必填
        payVo.setSubject(orderItemEntity.getSpuName());// 订单名称 必填
        payVo.setTotal_amount(payAmount.toString()); // 付款金额 必填
        payVo.setBody(orderItemEntity.getSkuAttrsVals()); //// 商品描述 可空
        return payVo;
    }


    @Override
    public PageUtils listWithItem(Map<String, Object> params) {
        //从拦截器中拿到用户信息
        MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();
        Long memberId = memberResponseVo.getId();

        //根据用户id获取最新的订单信息
        IPage<OrderEntity> page = this.page(
                new Query<OrderEntity>().getPage(params),
                new LambdaQueryWrapper<OrderEntity>().eq(OrderEntity::getMemberId, memberId)
                        .orderByDesc(OrderEntity::getId)//根据id可以拿到最新下单的数据(推荐用下单时间字段)
        );

        List<OrderEntity> orders = page.getRecords();
        List<OrderEntity> collect = orders.stream().map(
                order -> {
                    //获取订单号
                    String orderSn = order.getOrderSn();
                    //根据订单号获取订单项
                    List<OrderItemEntity> orderItems = orderItemService.list(
                            new LambdaQueryWrapper<OrderItemEntity>()
                                    .eq(OrderItemEntity::getOrderSn, orderSn)
                    );
                    order.setItems(orderItems);
                    return order;
                }
        ).collect(Collectors.toList());

        page.setRecords(collect);
        return new PageUtils(page);
    }

    @Override
    public void handlerPayResult(PayAsyncVo payAsyncVo) {
        //保存交易流水
        PaymentInfoEntity paymentInfoEntity = new PaymentInfoEntity();
        //订单号
        String orderSn = payAsyncVo.getOut_trade_no();
        paymentInfoEntity.setOrderSn(orderSn);
        paymentInfoEntity.setAlipayTradeNo(payAsyncVo.getTrade_no());//支付宝交易流水号
        paymentInfoEntity.setSubject(payAsyncVo.getSubject());
        String trade_status = payAsyncVo.getTrade_status();
        paymentInfoEntity.setPaymentStatus(trade_status);
        paymentInfoEntity.setCreateTime(new Date());
        paymentInfoEntity.setCallbackTime(payAsyncVo.getNotify_time());

        //判断交易状态是否成功
        if (trade_status.equals("TRADE_SUCCESS") || trade_status.equals("TRADE_FINISHED")) {
            orderDao.updateOrderStatus(orderSn, OrderStatusEnum.PAYED.getCode());
        }


    }

    @Override
    public void createSeckillOrder(SeckillOrderTo seckillOrder) {

        MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();

        //TODO 保存订单信息
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setOrderSn(seckillOrder.getOrderSn());
        orderEntity.setMemberId(seckillOrder.getMemberId());
        if (memberResponseVo!=null) {
            orderEntity.setMemberUsername(memberResponseVo.getUsername());
        }
        orderEntity.setStatus(OrderStatusEnum.CREATE_NEW.getCode());
        orderEntity.setCreateTime(new Date());
        BigDecimal payAmount = seckillOrder.getSeckillPrice().multiply(new BigDecimal(seckillOrder.getNum()));
        orderEntity.setPayAmount(payAmount);

        this.save(orderEntity);

        //TODO 保存订单项信息
        R r = productFeignService.info(seckillOrder.getSkuId());
        if (r.getCode()==0) {
            OrderItemEntity orderItemEntity = new OrderItemEntity();
            orderItemEntity.setOrderSn(seckillOrder.getOrderSn());
            orderItemEntity.setRealAmount(payAmount);
            orderItemEntity.setSkuQuantity(seckillOrder.getNum());

            //TODO 获取当前SKU的详细信息进行设置
            SeckillSkuInfoVo skuInfo = r.getData("skuInfo", new TypeReference<SeckillSkuInfoVo>() {
            });
            orderItemEntity.setSpuId(skuInfo.getSpuId());
            orderItemEntity.setCategoryId(skuInfo.getCatalogId());
            orderItemEntity.setSkuId(skuInfo.getSkuId());
            orderItemEntity.setSkuName(skuInfo.getSkuName());
            orderItemEntity.setSkuPrice(skuInfo.getPrice());
            orderItemEntity.setSkuPic(skuInfo.getSkuDefaultImg());
            orderItemService.save(orderItemEntity);

        }
    }

    private void saveOrder(OrderCreateTo orderCreateTo) {

        OrderEntity order = orderCreateTo.getOrder();
        order.setCreateTime(new Date());
        order.setModifyTime(new Date());
        this.save(order);

        orderItemService.saveBatch(orderCreateTo.getOrderItems());

    }


    public OrderCreateTo createOrder(MemberResponseVo memberResponseVo, OrderSubmitVo vo){
        
        OrderCreateTo orderCreateTo = new OrderCreateTo();
        //1.生成订单号
        String orderSn = IdWorker.getTimeId();
        //创建订单号
        OrderEntity orderEntity= buildOrder(memberResponseVo ,orderSn, vo);

        //2. 获取所有的订单项
        List<OrderItemEntity> orderItemEntities = buildOrderItems(orderSn);

        //3.计算相关价格
        computePrice(orderEntity, orderItemEntities);
        orderCreateTo.setOrder(orderEntity);
        orderCreateTo.setOrderItems(orderItemEntities);


        return orderCreateTo;
    }

    /**
     * 根据每个订单项设置订单的总额、促销、优惠券、积分、成长值
     * @param orderEntity
     * @param orderItemEntities
     */
    private void computePrice(OrderEntity orderEntity, List<OrderItemEntity> orderItemEntities) {

        //设置订单总额、促销、优惠券、积分、成长值
        BigDecimal total = new BigDecimal("0.0");
        BigDecimal promotion = new BigDecimal("0.0");
        BigDecimal coupon = new BigDecimal("0.0");
        BigDecimal integration = new BigDecimal("0.0");
        BigDecimal gift = new BigDecimal("0.0");
        BigDecimal growth = new BigDecimal("0.0");
        for (OrderItemEntity orderItem : orderItemEntities) {
            promotion = promotion.add(orderItem.getPromotionAmount());
            coupon = coupon.add(orderItem.getCouponAmount());
            integration = integration.add(orderItem.getIntegrationAmount());
            gift = gift.add(new BigDecimal(orderItem.getGiftIntegration().toString()));
            growth = growth.add(new BigDecimal(orderItem.getGiftGrowth().toString()));
            total = total.add(orderItem.getRealAmount());
        }
        //设置订单总额
        orderEntity.setTotalAmount(total);
        //设置应付总额
        orderEntity.setPayAmount(total.add(orderEntity.getFreightAmount()));//实际价格 + 运费
        //设置各种信息
        orderEntity.setPromotionAmount(promotion);
        orderEntity.setCouponAmount(coupon);
        orderEntity.setIntegrationAmount(integration);
        orderEntity.setIntegration(gift.intValue());
        orderEntity.setGrowth(growth.intValue());

        //设置删除状态(0-未删除，1-已删除)
        orderEntity.setDeleteStatus(0);

    }

    private OrderEntity buildOrder(MemberResponseVo memberResponseVo, String orderSn, OrderSubmitVo orderSubmitVo) {
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setOrderSn(orderSn);
        //获取收货人信息、运费信息
        // OrderSubmitVo orderSubmitVo = submitVoThreadLocal.get();
        //设置用户信息
        orderEntity.setMemberId(memberResponseVo.getId());
        orderEntity.setMemberUsername(memberResponseVo.getUsername());
        FareVo fareVo = wmsFeignService.getFare(orderSubmitVo.getAddrId());
        System.out.println(fareVo);
        //设置运费信息
        orderEntity.setFreightAmount(fareVo.getFare());
        //设置收货人信息
        orderEntity.setReceiverCity(fareVo.getMemberAddressVo().getCity());
        orderEntity.setReceiverDetailAddress(fareVo.getMemberAddressVo().getDetailAddress());
        orderEntity.setReceiverName(fareVo.getMemberAddressVo().getName());
        orderEntity.setReceiverPhone(fareVo.getMemberAddressVo().getPhone());
        orderEntity.setReceiverPostCode(fareVo.getMemberAddressVo().getPostCode());
        orderEntity.setReceiverProvince(fareVo.getMemberAddressVo().getProvince());
        orderEntity.setReceiverRegion(fareVo.getMemberAddressVo().getRegion());

        //设置订单相关相关的状态信息
        orderEntity.setStatus(OrderStatusEnum.CREATE_NEW.getCode());
        orderEntity.setConfirmStatus(0);
        orderEntity.setAutoConfirmDay(7);
        return orderEntity;
    }

    /**
     * 构建所有的订单项数据
     * @return
     */
    private List<OrderItemEntity> buildOrderItems(String orderSn) {

        List<OrderItemEntity> collect = cartFeignService.getCurrentUserCartItems().stream().map((item) -> {
            OrderItemEntity orderItemEntity = buildOrderItem(item);
            orderItemEntity.setOrderSn(orderSn);
            return orderItemEntity;
        }).collect(Collectors.toList());

        return collect;

    }

    /**
     * 构建某一个订单项
     * @param orderItemVo
     * @return
     */
    private OrderItemEntity buildOrderItem(OrderItemVo orderItemVo) {

        OrderItemEntity orderItemEntity = new OrderItemEntity();

        //1.订单信息 订单号 v
        //2. 商品spu信息 v
        R r = productFeignService.getSpuInfoBySkuId(orderItemVo.getSkuId());
        if (r.getCode()==0) {
            SpuInfoTo spuInfoTo = r.getData(new TypeReference<SpuInfoTo>() {
            });
            orderItemEntity.setSpuId(spuInfoTo.getId());
            orderItemEntity.setSpuName(spuInfoTo.getSpuName());
            orderItemEntity.setSpuBrand(spuInfoTo.getBrandId().toString());
            orderItemEntity.setCategoryId(spuInfoTo.getCatalogId());

        }

        //3. 商品sku信息 v
        orderItemEntity.setSkuId(orderItemVo.getSkuId());
        orderItemEntity.setSkuName(orderItemVo.getTitle());
        orderItemEntity.setSkuPic(orderItemVo.getDefaultImg());
        orderItemEntity.setSkuPrice(orderItemVo.getPrice());
        orderItemEntity.setSkuQuantity(orderItemVo.getCount());
        String attrs = StringUtils.collectionToDelimitedString(orderItemVo.getSkuAttr(), ";");
        orderItemEntity.setSkuAttrsVals(attrs);
        //4. 商品优惠信息(不做)

        //5. 积分信息 v
        orderItemEntity.setGiftGrowth(orderItemVo.getPrice()
                .multiply(new BigDecimal(orderItemVo.getCount().toString())).intValue());
        orderItemEntity.setGiftIntegration(orderItemVo.getPrice()
                .multiply(new BigDecimal(orderItemVo.getCount().toString())).intValue());

        //6.计算单个订单项的真实价格
        orderItemEntity.setPromotionAmount(new BigDecimal("0"));
        orderItemEntity.setCouponAmount(new BigDecimal("0"));
        orderItemEntity.setIntegrationAmount(new BigDecimal("0"));

        BigDecimal totalPrice = orderItemEntity.getSkuPrice().multiply(new BigDecimal(orderItemEntity.getSkuQuantity().toString()));
        BigDecimal subtract = totalPrice.subtract(orderItemEntity.getPromotionAmount())
                .subtract(orderItemEntity.getCouponAmount())
                .subtract(orderItemEntity.getIntegrationAmount());
        orderItemEntity.setRealAmount(subtract);

        return orderItemEntity;
    }


}